package com.itsu.manage.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.*;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itsu.interfaces.entity.*;
import com.itsu.interfaces.service.*;
import com.itsu.manage.controller.SystemController;
import com.itsu.manage.exception.MyException;
import com.itsu.manage.interceptor.UserThreadLocal;
import com.itsu.pojo.constants.Constants;
import com.itsu.pojo.enums.CommentType;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import com.itsu.pojo.vo.*;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.lucene.queryparser.surround.query.SrndTruncQuery;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AppManageUserService {

    @Reference
    ManageUserService manageUserService;

    @Reference
    UserService userService;

    @Reference
    UserInfoService userInfoService;

    @Reference
    UserFreezeService userFreezeService;

    @Reference
    UserLoginService userLoginService;

    @Reference
    UserLikeService userLikeService;

    @Reference
    VideoService videoService;

    @Reference
    CommentService commentService;

    @Reference
    PublishService publishService;

    @Reference
    PublishStateService publishStateService;

    static String[] city = {"上海", "杭州", "波士顿", "加拿大", "台湾"};
    static String[] device = {"小米手机", "苹果手机", "苹果电脑", "华为手机", "苹果手表"};

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    private final Logger logger = LoggerFactory.getLogger(AppManageUserService.class);

    public Map<String, Object> login(Map<String, String> map) {
        String username = map.get("username");
        String password = map.get("password");
        String verificationCode = map.get("verificationCode");
        String uuid = map.get("uuid");
        String code = redisTemplate.opsForValue().get("IMAGE_CODE" + uuid);
        if (StrUtil.isEmpty(code)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_TIMEOUT));
        }

        if (!code.equals(verificationCode)) {
            throw new MyException(new ErrorResult(ResultCode.VALIDATOR_CODE_ERROR));
        }

        ManageUser manageUser = manageUserService.login(username, password);
        if (ObjectUtil.isEmpty(manageUser)) {
            throw new MyException(new ErrorResult(ResultCode.ERROR));
        }
        Map<String, Object> date = new HashMap<>();
        //设置token
        Map<String, Object> jwtMap = new HashMap<>();
        jwtMap.put("username", manageUser.getUsername());
        jwtMap.put("uid", manageUser.getId());
        jwtMap.put(JWTPayload.EXPIRES_AT, DateTime.of(System.currentTimeMillis() + Constants.JWT_TIME_OUT));
        // 载荷信息，密钥信息
        String token = JWTUtil.createToken(jwtMap, Constants.JWT_SECRET.getBytes());
        logger.info("生成的token:{}", token);
        date.put("token", token);
        return date;
    }

    public Map<String, String> loginProfile() {
        Map<String, String> date = new HashMap<>();
        ManageUser user = manageUserService.findUser(UserThreadLocal.getUid());
        if (ObjectUtil.isEmpty(user)) {
            throw new MyException(new ErrorResult(ResultCode.ERROR));
        }
        date.put("uid", user.getId().toString());
        date.put("username", user.getUsername());
        date.put("avatar", user.getAvatar());

        return date;
    }


    public PageResult getPageUsers(Integer page, Integer pageSize, Long uid, String nickName, String city) {

        String selectCity = null;

        if (StrUtil.isNotBlank(city)) {
            if ("黑龙江省".equals(city) || "内蒙古自治区".equals(city)) {
                selectCity = city.substring(0,3);
            } else {
                selectCity = city.substring(0,2);
            }

        }
        Page<UserInfoEntity> pageUserInfo = userInfoService.pageUsers(page, pageSize, uid, nickName, selectCity);
        List<UserInfoEntity> records = pageUserInfo.getRecords();
        List<ManageUserInfoVo> data = new ArrayList<>();
        for (UserInfoEntity entity : records) {
            ManageUserInfoVo vo = new ManageUserInfoVo();
            vo.setId(Convert.toInt(entity.getUserId()));
            vo.setLogo(entity.getLogo());
            vo.setNickname(entity.getNickName());
            vo.setMobile(RandomUtil.randomString(11));
            vo.setSex(entity.getSex() == 1 ? "女" : "男");
            vo.setAge(entity.getAge());
            vo.setCity(entity.getCity());
            UserFreeze freeze = userFreezeService.findByUid(entity.getUserId());
            vo.setUserStatus(ObjectUtil.isEmpty(freeze) ? "1" : "2");
            UserLogin userLogin = userLoginService.findUserByUid(entity.getUserId());
            if (ObjectUtil.isNotEmpty(userLogin)) {
                vo.setLastActiveTime(userLogin.getLoginTime().getTime());
            } else {
                vo.setLastActiveTime(entity.getCreated().getTime());
            }
            data.add(vo);
        }

        return new PageResult(page, pageSize, pageUserInfo.getTotal(), data);
    }

    public UserProfileVo getUserProfile(Long id) {
        UserInfoEntity entity = userInfoService.findUserByUid(id);
        UserEntity userEntity = userService.findUserById(id);
        List<UserLike> likeList = userLikeService.findLikeList(UserThreadLocal.getUid());
        List<Long> likeUserIds = CollUtil.getFieldValues(likeList, "likeUserId", Long.class);
        List<UserLike> fanList = userLikeService.findFanList(UserThreadLocal.getUid());
        Map<Long, UserLike> fanListMap = CollUtil.fieldValueMap(fanList, "userId");
        Long eachLoveCount = 0L;
        for (Long likeUserId : likeUserIds) {
            UserLike userLike = fanListMap.get(likeUserId);
            if (ObjectUtil.isNotEmpty(userLike)) {
                eachLoveCount++;
            }
        }

        UserProfileVo vo = new UserProfileVo();
        vo.setId(Convert.toInt(userEntity.getId()));
        vo.setNickname(entity.getNickName());
        vo.setMobile(userEntity.getMobile());
        vo.setSex(entity.getSex() == 1 ? "女性" : "男性");
        vo.setPersonalSignature(entity.getSign());
        vo.setAge(entity.getAge());
        vo.setCountBeLiked(ObjectUtil.isEmpty(likeList) ? 0 : Convert.toInt(fanList.size()));
        vo.setCountLiked(ObjectUtil.isEmpty(likeList) ? 0 : Convert.toInt(likeList.size()));
        vo.setCountMatching(Convert.toInt(eachLoveCount));
        vo.setIncome(Convert.toInt(entity.getIncome()));
        UserFreeze freeze = userFreezeService.findByUid(id);
        vo.setUserStatus(ObjectUtil.isEmpty(freeze) ? "1" : "2");
        vo.setCreated(userEntity.getCreated().getTime());
        vo.setCity(entity.getCity());
        UserLogin userLogin = userLoginService.findUserByUid(entity.getUserId());
        vo.setLastActiveTime(userLogin.getLoginTime().getTime());
        vo.setLastLoginLocation(city[RandomUtil.randomInt(5)]);
        vo.setLogo(entity.getLogo());
        vo.setTags(entity.getTags());

        return vo;

    }

    public Map<String, String> freezeUser(Map<String, String> map) {
        Date date = new Date();
        //冻结时间，1为冻结3天，2为冻结7天，3为永久冻结
        String userId = map.get("userId");
        String freezingTime = map.get("freezingTime");
        String freezingRange = map.get("freezingRange");
        String reasonsForFreezing = map.get("reasonsForFreezing");
        String frozenRemarks = map.get("frozenRemarks");
        UserFreeze userFreeze = new UserFreeze();
        userFreeze.setUserId(Convert.toLong(userId));
        userFreeze.setFreezingTime(Convert.toInt(freezingTime));
        userFreeze.setFreezingRange(Convert.toInt(freezingRange));
        userFreeze.setReason(reasonsForFreezing);
        userFreeze.setRemark(frozenRemarks);
        if ("1".equals(freezingTime)) {
            userFreeze.setThawTime(DateUtils.addDays(date, 3));
        }

        if ("2".equals(freezingTime)) {
            userFreeze.setThawTime(DateUtils.addDays(date, 7));
        }

        if ("3".equals(freezingTime)) {
            userFreeze.setThawTime(DateUtils.addYears(date, 9999));
        }

        int i = userFreezeService.addUserFreeze(userFreeze);
        Map<String, String> data = new HashMap<>();
        data.put("message", "操作成功");

        if (i == 0) {
            data.put("message", "操作失败");
        }

        return data;
    }

    public Map<String, String> unfreezeUser(Map<String, String> map) {
        String userId = map.get("userId");
        int i = userFreezeService.deleteUserFreezeByUid(Convert.toLong(userId));
        Map<String, String> data = new HashMap<>();
        data.put("message", "操作成功");

        if (i == 0) {
            data.put("message", "操作失败");
        }
        return data;
    }


    public PageResult userLoginLogs(Integer page, Integer pageSize, String sortProp, String sortOrder, Long uid) {

        Page<UserLogin> pageLogin = userLoginService.pageLoginLogs(page, pageSize, StrUtil.sub(sortOrder, 0, -6), uid);
        List<UserLogin> records = pageLogin.getRecords();
        List<LoginLogVo> vo = new ArrayList<>();
        for (UserLogin record : records) {
            LoginLogVo loginLogVo = new LoginLogVo();
            loginLogVo.setId(record.getId());
            loginLogVo.setLogTime(record.getLoginTime().getTime());
            loginLogVo.setPlace(city[RandomUtil.randomInt(5)]);
            loginLogVo.setEquipment(device[RandomUtil.randomInt(5)]);
            vo.add(loginLogVo);
        }
        return new PageResult(page, pageSize, pageLogin.getTotal(), vo);
    }

    public PageResult userVideoLogs(Integer page, Integer pageSize, String sortProp, String sortOrder, Long uid) {
        List<Video> list = videoService.pageVideoLogs(page, pageSize, sortProp, StrUtil.sub(sortOrder, 0, -6), uid);
        List<VideoLogVo> vo = list.stream().map(video -> {
            VideoLogVo videoLogVo = new VideoLogVo();
            videoLogVo.setId(Convert.toLong(video.getId()));
            videoLogVo.setUserId(video.getUserId());
            UserInfoEntity userInfo = userInfoService.findUserByUid(video.getUserId());
            videoLogVo.setNickname(userInfo.getNickName());
            videoLogVo.setVideoUrl(video.getVideoUrl());
            videoLogVo.setPicUrl(video.getPicUrl());
            videoLogVo.setReportCount(RandomUtil.randomLong(100L));
            videoLogVo.setForwardingCount(RandomUtil.randomLong(10L));
            videoLogVo.setLikeCount(commentService.queryLikedCount(video.getId()));
            videoLogVo.setCommentCount(commentService.queryCommentCount(video.getId()));
            videoLogVo.setCreateDate(video.getCreated());

            return videoLogVo;

        }).collect(Collectors.toList());

        return new PageResult(page, pageSize, Convert.toLong(list.size()), vo);
    }


    public MsgPageResult messageLogs(Integer page, Integer pageSize, String sortProp, String sortOrder
            , Long uid, Long id, Long sd, Long ed, String state) {
        //获取对应条件的动态
        List<Publish> list = publishService.MessageLogs(StrUtil.sub(sortOrder, 0, -6), uid, id,
                sd, ed);

        //获取动态string - publishID
        List<String> idList = new ArrayList<>();
        for (Publish p : list) {
            idList.add(p.getId().toHexString());
        }

        List<PublishState> startList = publishStateService.findByPublishIds(idList);

        //获取对应条件的动态状态
        List<PublishState> midList = getLastList(state, startList);

        //获取分页信息
        List<PublishState> stateList = CollUtil.sub(midList, (page - 1)*pageSize, NumberUtil.min(page * pageSize, midList.size()));

        List<MessageLogVo> vo = stateList.stream().map(obj -> {
            MessageLogVo messageLogVo = new MessageLogVo();
            Publish publish = publishService.findOneById(new ObjectId(obj.getPublishId()));
            messageLogVo.setId(publish.getId().toHexString());
            messageLogVo.setUserId(publish.getUserId());
            //null point
            UserInfoEntity userInfo = userInfoService.findUserByUid(publish.getUserId());
            messageLogVo.setNickname(userInfo.getNickName());
            messageLogVo.setUserLogo(userInfo.getLogo());
            messageLogVo.setText(publish.getText());
            messageLogVo.setState(obj.getState());
            messageLogVo.setReportCount(RandomUtil.randomLong(10));
            messageLogVo.setLikeCount(commentService.queryLikedCount(publish.getId()));
            messageLogVo.setCommentCount(commentService.queryCommentCount(publish.getId()));
            messageLogVo.setForwardingCount(RandomUtil.randomLong(19));
            messageLogVo.setMedias(publish.getMedias());
            messageLogVo.setCreateDate(publish.getCreated());
            return messageLogVo;
        }).collect(Collectors.toList());

        List<StateTotalVo> totals = getTotals(startList);
        return new MsgPageResult(page, pageSize, Convert.toLong(midList.size()), vo, totals);
    }

    public MessageProfileVo messagesProfile(String id) {
        Publish publish = publishService.findOneById(new ObjectId(id));
        UserInfoEntity userInfo = userInfoService.findUserByUid(publish.getUserId());
        PublishState publishState = publishStateService.findByPublishId(id);
        MessageProfileVo profileVo = new MessageProfileVo();
        profileVo.setId(id);
        profileVo.setUserId(publish.getUserId());
        profileVo.setNickname(userInfo.getNickName());
        profileVo.setUserLogo(userInfo.getLogo());
        profileVo.setText(publish.getText());
        profileVo.setTopState(publishState.getTopState());
        profileVo.setState(publishState.getState());
        profileVo.setReportCount(RandomUtil.randomLong(10));
        profileVo.setLikeCount(commentService.queryLikedCount(publish.getId()));
        profileVo.setCommentCount(commentService.queryCommentCount(publish.getId()));
        profileVo.setForwardingCount(RandomUtil.randomLong(19));
        profileVo.setMedias(publish.getMedias());
        profileVo.setCreateDate(publish.getCreated());
        return profileVo;
    }


    public PageResult messageComments(Integer page, Integer pageSize, String sortProp, String sortOrder, String messageId) {
        List<Comment> comments = commentService.getComments(new ObjectId(messageId),
                CommentType.COMMENT.getValue(), StrUtil.sub(sortOrder, 0, -6));

        List<Comment> list = CollUtil.sub(comments, (page - 1) * pageSize,
                NumberUtil.min(page * pageSize, comments.size()));
        List<MessageComProfileVo> vo = list.stream().map(obj -> {
            MessageComProfileVo messageComProfileVo = new MessageComProfileVo();
            messageComProfileVo.setId(obj.getId().toHexString());
            messageComProfileVo.setUserId(obj.getUserId());
            messageComProfileVo.setContent(obj.getContent());
            UserInfoEntity userByUid = userInfoService.findUserByUid(obj.getUserId());
            messageComProfileVo.setNickname(userByUid.getNickName());
            messageComProfileVo.setCreateDate(obj.getCreated());
            return messageComProfileVo;
        }).collect(Collectors.toList());
        return new PageResult(page, pageSize, Convert.toLong(comments.size()), vo);
    }

    public Map<String, String> messageTop(String id) {
        Map<String, String> data = new HashMap<>();
        int i = publishStateService.updatePublishStateByPublishId(PublishState.builder().publishId(id).topState(2).build());
        data.put("message","操作失败");
        if (i == 1) {
            data.put("message","操作成功");
        }
        return data;
    }

    public Map<String, String> messagesUnTop(String id) {
        Map<String, String> data = new HashMap<>();
        int i = publishStateService.updatePublishStateByPublishId(PublishState.builder().publishId(id).topState(1).build());
        data.put("message","操作失败");
        if (i == 1) {
            data.put("message","操作成功");
        }
        return data;
    }

    //审核状态，1为待审核，2为自动审核通过，3为待人工审核，4为人工审核拒绝，5为人工审核通过，6为自动审核拒绝
    public Map<String, String> messagesState(List<String> ids, String state) {
        Map<String, String> data = new HashMap<>();
        int i = publishStateService.updatePublishStateByPublishIds(ids, state);
        data.put("message","操作失败");
        if (i == 1) {
            data.put("message","操作成功");
        }
        return data;
    }

    //pageList - PublishState

    private List<PublishState> getLastList(String state, List<PublishState> startList) {
        List<PublishState> midList = startList;
        if (StrUtil.isNotBlank(state) && !"all".equals(state)) {
            midList = startList.stream().filter(obj ->
                StrUtil.equals(state, obj.getState())
            ).collect(Collectors.toList());
        }
        return midList;
    }
    //publish 状态合计

    private List<StateTotalVo> getTotals(List<PublishState> list) {
        List<String> idList = CollUtil.getFieldValues(list, "publishId", String.class);
        List<PublishState> psList = publishStateService.findByPublishIds(idList);
        List<StateTotalVo> totalVos = new ArrayList<>();
        StateTotalVo all = new StateTotalVo();
        all.setTitle("全部");
        all.setCode("all");
        all.setValue(psList.size());
        totalVos.add(all);
        //待审核数目
        int waitCount = CollUtil.count(psList, publishState -> {
            if ("3".equals(publishState.getState())) {
                return true;
            }
            return false;
        });
        StateTotalVo wait = new StateTotalVo();
        wait.setTitle("待审核,");
        wait.setCode("3");
        wait.setValue(waitCount);
        totalVos.add(wait);

        //已通过数目
        int passCount = CollUtil.count(psList, publishState -> {
            if ("4".equals(publishState.getState())) {
                return true;
            }
            return false;
        });
        StateTotalVo pass = new StateTotalVo();
        pass.setTitle("已通过");
        pass.setCode("4");
        pass.setValue(passCount);
        totalVos.add(pass);
        //已驳回数目
        int reCount = CollUtil.count(psList, publishState -> {
            if ("5".equals(publishState.getState())) {
                return true;
            }
            return false;
        });

        StateTotalVo re = new StateTotalVo();
        re.setTitle("已驳回");
        re.setCode("5");
        re.setValue(reCount);
        totalVos.add(re);

        return totalVos;

    }

}
